package org.je.xml;

import org.je.ufo.Int;
import org.je.util.CharUtil;
import org.je.util.StringUtil;




/**
 * 这个类用户分析标签类的属性
 * 
 * @author fyf
 */
class XmlAttrUtil
{

	/**
	 * 
	 * @param xml
	 * @param offset
	 * @param isHead
	 * @return
	 */
	public static String getAttName(String xml, Int offset, boolean isHead) {
		int n = XmlGramUtil.nextNotBlank(xml ,offset.val());

		if (n == -1) {
			throw new ParseXmlException(XmlGramUtil.error(xml ,"tag is not finished" ,offset.val()));
		}

		char c1 = xml.charAt(n);

		if (isHead) {
			if (c1 == '?') {
				if (n + 1 < xml.length() && xml.charAt(n + 1) == '>') {
					// offset[0] = n + 2;// update
					offset.val(n + 2);
					return "?>";
				}
				throw new ParseXmlException(XmlGramUtil.error(xml ,"find attribute error" ,offset.val()));
			}
		} else {
			if (c1 == '>') {
				// offset[0] = n + 1;// update
				offset.val(n + 1);
				return ">";
			}

			if (c1 == '/') {
				if (n + 1 < xml.length() && xml.charAt(n + 1) == '>') {
					// offset[0] = n + 2;// update
					offset.val(n + 2);
					return "/>";
				}

				throw new ParseXmlException(XmlGramUtil.error(xml ,"find attribute error" ,offset.val()));
			}
		}

		if (!CharUtil.isNameStartChar(c1)) {
			throw new ParseXmlException(XmlGramUtil.error(xml ,"illegal name start char[" + c1 + "]" ,offset.val()));
		}

		for (int i = n + 1; i < xml.length(); ++i) {
			char c = xml.charAt(i);

			if (c == '=' || CharUtil.isBlank(c)) {
				// offset[0] = i;// update
				offset.val(i);
				return xml.substring(n ,i);
			}

			if (!isNameChar(c)) {
				throw new ParseXmlException(XmlGramUtil.error(xml ,"illegal attribute name char[" + c + "]" ,offset.val()));
			}

		}

		throw new ParseXmlException(XmlGramUtil.error(xml ,"attribute name is not finished" ,offset.val()));
	}

	public static void findEqSymbol(String xml, Int offset) {
		int n = XmlGramUtil.nextNotBlank(xml ,offset.val());

		if (n > 0 && xml.charAt(n) == '=') {
			// offset[0] = n + 1;
			offset.val(n + 1);
			return;
		}

		throw new ParseXmlException(XmlGramUtil.error(xml ,"attribute's next is a =." ,offset.val()));
	}

	public static String getAttValue(String xml, Int offset, boolean isHead) {

		int n = XmlGramUtil.nextNotBlank(xml ,offset.val());

		if (n == -1) {
			throw new ParseXmlException(XmlGramUtil.error(xml ,"cant find attribute value" ,n));
		}

		char symbol = xml.charAt(n);

		if (! (symbol == '\'' || symbol == '\"')) {
			throw new ParseXmlException(XmlGramUtil.error(xml ,"attribute must start with [',\"] " ,n));
		}

		for (int i = n + 1; i < xml.length(); ++i) {
			if (xml.charAt(i) == symbol) {
				if (i < xml.length() - 1) {
					char c2 = xml.charAt(i + 1);

					if (!isHead) {
						if (CharUtil.isBlank(c2) || c2 == '>' || c2 == '/') {
							// offset[0] = i + 1;
							offset.val(i + 1);
							return xml.substring(n + 1 ,i);
						}
					} else {
						if (CharUtil.isBlank(c2) || c2 == '?') {
							// offset[0] = i + 1;
							offset.val(i + 1);
							return xml.substring(n + 1 ,i);
						}
					}
				}
				throw new ParseXmlException(XmlGramUtil.error(xml ,"attributes has not gap." ,n));
			}
		}

		throw new ParseXmlException(XmlGramUtil.error(xml ,"attribute is not finished" ,n));

	}

	public static boolean isNameChar(char c) {
		return CharUtil.isNameChar(c) || c == '-' || c == ':' || c == '.';
	}

	public static boolean isNameStr(String str) {
		if (StringUtil.isBlank(str)) {
			return false;
		}
		if (!CharUtil.isNameStartChar(str.charAt(0))) {
			return false;
		}

		for (int i = 1; i < str.length(); ++i) {
			if (!isNameChar(str.charAt(i))) {
				return false;
			}
		}
		return true;
	}

}
